home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctj8307.arc
/
XB.BAS
< prev
Wrap
BASIC Source File
|
1983-05-06
|
14KB
|
580 lines
1 ' File: xb.bas
2 ' Auth: Richard Foard
3 ' Edit: rmf 13-Mar-83 10:00pm
4 ' Copyright (c) 1982 Richard M. Foard
5 '
6 DIM LABSTK(25),GLABVALS(1000),ULABVALS(1000),ULABTEXT$(1000)
899 GOTO 1000
900 DEF FNALPHA(C$)=(C$>="a" AND C$<="z") OR (C$>="A" AND C$<="Z")
901 DEF FNNUMERIC(C$)=C$>="0" AND C$<="9"
903 DEF FNUPPER$(C$)=CHR$(+32*(C$>="a")+ASC(C$))
999 RETURN
1000 PASS=1
1010 GOSUB 10000 'initialize
2000 GOSUB 31000 'readline
2200 GOSUB 4000 'proc line
2400 IF NOT(EOF(INCHAN)) THEN 2000
2460 GOSUB 55000 'pass 2
2465 GOSUB 55200 'finish ulabs
2467 GOSUB 55500 'finish errs
2470 CLOSE INCHAN
2480 CLOSE OUTCHAN
2490 PRINT "Compilation complete"
2500 STOP
4000 '----------
4010 ' proc line
4020 '
4030 GOSUB 50500 'scan nb
4032 IF FNNUMERIC(TOKEN$) THEN 4030 'skip line numbers
4034 WHILE TTYPE=ULAB
4035 GOSUB 46000 'def ulab
4036 GOSUB 50500 'scan nb
4037 WEND
4039 IF TTYPE=EOL THEN RETURN
4040 IF TTYPE=SCANERROR THEN RETURN
4050 IF TTYPE <> SNAME THEN 4600
4060 IF TOKEN$ <> "IF" THEN 4090
4070 GOSUB 40000 'proc if
4080 RETURN
4090 IF TOKEN$ <> "ELSE" THEN 4120
4100 GOSUB 40500 'proc else
4110 RETURN
4120 IF TOKEN$ <> "ELSEIF" THEN 4150
4130 GOSUB 41000 'proc elseif
4140 RETURN
4150 IF TOKEN$ <> "ENDIF" THEN 4170
4160 GOSUB 41500 'proc endif
4165 RETURN
4170 IF TOKEN$ <> "REPEAT" THEN 4200
4180 GOSUB 42000 'proc repeat
4190 RETURN
4200 IF TOKEN$ <> "WHILE" THEN 4230
4210 GOSUB 42500 'proc while
4220 RETURN
4230 IF TOKEN$ <> "UNTIL" THEN 4260
4240 GOSUB 43000 'proc until
4250 RETURN
4260 IF TOKEN$ <> "ENDREP" THEN 4320
4270 GOSUB 43500 'proc endrep
4280 RETURN
4320 IF TOKEN$ <> "DO" THEN 4350
4330 GOSUB 44500 'proc do
4340 RETURN
4350 IF TOKEN$ <> "PROCEDURE" THEN 4380
4360 GOSUB 45000 'proc procedure
4370 RETURN
4380 IF TOKEN$ <> "ENDPROC" THEN 4600
4390 GOSUB 45500 'proc endproc
4400 RETURN
4600 'endif
4660 GOSUB 59000 'copy to eol
4670 GOSUB 30200 'putline
4999 RETURN
10000 '----------
10010 ' initialize
10020 '
10030 GOSUB 21000 'init scan
10040 GOSUB 30000 'init put
10050 GOSUB 30500 'init labtabs
10060 GOSUB 30700 'init labstk
10070 GOSUB 31500 'init readline
10080 GOSUB 900 'define functions
10090 GOSUB 50000 'init symtabs
10100 GOSUB 53000 'init files
10110 GOSUB 51000 'init screen
10999 RETURN
20000 '----------
20010 'scan --
20020 ' sets 'token$' = next token in 'inline$'
20030 ' 'ttype' = token class
20040 '
20050 IF ASC(CHAR$)<>EOL AND ASC (CHAR$) <> 12 THEN 20090
20060 TTYPE=EOL
20070 TOKEN$=""
20080 GOTO 20550
20090 'elseif
20100 IF ASC(CHAR$)<>&O42 THEN 20140
20110 GOSUB 21500 'proc quoted
20130 GOTO 20550
20140 'elseif
20280 IF CHAR$<>"@" THEN 20390
20290 GOSUB 21400 'nxtc u
20360 GOSUB 23110 'proc ulab
20380 GOTO 20550
20390 'elseif
20400 IF NOT FNALPHA(CHAR$) THEN 20430
20420 GOSUB 23300 'proc name
20425 GOTO 20550
20430 'else
20440 IF CHAR$<>" " AND ASC(CHAR$) <> 9 THEN 20500
20450 TOKEN$=" "
20460 TTYPE=ASC(" ")
20470 GOSUB 21400 'nxtc u
20480 IF CHAR$=" " THEN 20470
20490 GOTO 20540
20500 'else
20510 TOKEN$=CHAR$
20520 TTYPE=ASC(CHAR$)
20530 GOSUB 21400 'nxtc u
20540 'endif
20550 'endif
20560 RETURN
20999 RETURN
21000 '----------
21010 ' init scan
21020 '
21030 EOL=1
21040 QSTR=2
21060 GLAB=3
21070 ULAB=4
21080 SNAME=5
21090 SCANERROR=6
21199 RETURN
21200 '----------
21210 ' init line scan
21220 '
21230 INLINELEN=LEN(INLINE$)
21240 INI=1
21250 GOSUB 21400 'nxtc u
21299 RETURN
21300 '----------
21310 ' nxtc -- sets 'char$' to next input character
21320 '
21330 IF INI<=INLINELEN THEN 21350
21340 CHAR$=CHR$(EOL)
21345 GOTO 21380
21350 'else
21360 CHAR$=MID$(INLINE$,INI,1)
21370 INI=INI+1
21380 'endif
21390 RETURN
21400 '----------
21410 ' nxtc u
21420 '
21430 GOSUB 21300 'nxtc
21440 CHAR$=FNUPPER$(CHAR$)
21499 RETURN
21500 '----------
21510 ' proc quoted
21520 '
21530 TOKEN$=CHR$(&O42)
21535 PQLEN=0
21540 GOSUB 21300 'nxtc
21550 IF ASC(CHAR$)=&O42 OR PQLEN=255 THEN 21590
21560 TOKEN$=TOKEN$+CHAR$
21570 PQLEN=PQLEN+1
21575 GOSUB 21300 'nxtc
21580 GOTO 21550
21590 'endloop
21600 IF PQLEN<255 THEN 21660
21610 ERMSG$="String too long"
21620 GOSUB 60000 'error
21630 TTYPE=SCANERROR
21640 TOKEN$=""
21650 GOTO 21690
21660 'else
21670 TOKEN$=TOKEN$+CHR$(&O42)
21680 TTYPE=QSTR
21685 GOSUB 21400 'nxtc u
21690 'endif
21799 RETURN
23100 '----------
23110 ' proc ulab
23120 '
23130 GOSUB 23300 'proc name
23140 IF TTYPE=SNAME THEN 23190
23150 ERMSG$="Improper user label"
23160 GOSUB 60000 'error
23170 TTYPE=SCANERROR
23180 TOKEN$=""
23185 GOTO 23210
23190 'else
23200 TTYPE=ULAB
23210 'endif
23299 RETURN
23300 '----------
23310 ' proc name
23320 '
23330 IF FNALPHA(CHAR$) THEN 23380
23340 ERMSG$="Improper name"
23350 GOSUB 60000 'error
23360 TTYPE=SCANERROR
23370 GOTO 23490
23380 'else
23385 TOKEN$=""
23390 IF (NOT FNALPHA(CHAR$)) AND (NOT FNNUMERIC(CHAR$)) THEN 23440
23400 TOKEN$=TOKEN$+CHAR$
23410 GOSUB 21400 'nxtc u
23420 GOTO 23390
23430 'endloop
23440 IF CHAR$<>"#" AND CHAR$<>"%" AND CHAR$<>"$" AND CHAR$<>"!" THEN 23470
23450 TOKEN$=TOKEN$+CHAR$
23460 GOSUB 21400 'nextc u
23470 'endif
23480 TTYPE=SNAME
23490 'endif
23999 RETURN
30000 '----------
30010 ' init put
30020 '
30030 OUTLINE$=" 10 "
30040 OUTNUM=10
30045 OUTINC=10
30099 RETURN
30100 '----------
30110 ' put -- appends 'out$' to 'outline$'
30120 '
30130 OUTLINE$=OUTLINE$+POUT$
30199 RETURN
30200 '----------
30210 ' putline
30220 '
30230 PRINT# OUTCHAN,OUTLINE$
30240 OUTNUM=OUTNUM+OUTINC
30250 OUTLINE$=STR$(OUTNUM)+" "
30499 RETURN
30500 '----------
30510 ' init labtabs
30520 '
30530 NEXTGLAB=65529!
30540 NEXTULAB=0
30599 RETURN
30600 '----------
30610 ' genlab -- sets 'label$', 'labelval'
30620 '
30630 LABEL$=STR$(NEXTGLAB)
30640 LABELVAL=NEXTGLAB
30650 NEXTGLAB=NEXTGLAB-1
30699 RETURN
30700 '----------
30710 ' init labstk
30720 '
30730 LABTOP=0
30799 RETURN
30800 '----------
30810 ' pushlab -- pushes 'labelval'
30820 '
30830 LABSTK(LABTOP)=LABELVAL
30840 LABTOP=LABTOP+1
30850 IF LABTOP>25 THEN PRINT "Label stack overflow": STOP
30899 RETURN
30900 '----------
30910 ' poplab -- pops 'labelval', set label$
30920 '
30930 LABTOP=LABTOP-1
30940 IF LABTOP<0 THEN PRINT "Label stack underflow": STOP
30950 LABELVAL=LABSTK(LABTOP)
30960 LABEL$=STR$(LABELVAL)
30999 RETURN
31000 '----------
31010 ' readline -- reads 'inline$'
31020 '
31030 LINE INPUT# INCHAN,INLINE$
31040 GOSUB 21200 'init line scan
31499 RETURN
31500 '----------
31510 ' init readline
31520 '
31999 RETURN
40000 '----------
40010 ' proc if
40020 '
40030 GOSUB 30600 'genlab
40040 GOSUB 30800 'pushlab
40050 GOSUB 30600 'genlab
40060 GOSUB 30800 'pushlab
40070 POUT$="IF NOT("
40080 GOSUB 30100 'put
40090 GOSUB 50500 'scan nb
40120 GOSUB 59000 'copy to eol
40130 POUT$=") THEN "+LABEL$
40140 GOSUB 30100 'put
40150 GOSUB 30200 'putline
40499 RETURN
40500 '----------
40510 ' proc else
40520 '
40530 GOSUB 30900 'poplab
40540 TVAL1=LABELVAL
40560 GOSUB 30900 'poplab
40570 POUT$="GOTO "+LABEL$
40580 GOSUB 30100 'put
40590 GOSUB 30200 'putline
40592 TVAL2=LABELVAL
40594 LABELVAL=TVAL1
40596 GOSUB 50100 'place glab
40598 LABELVAL=TVAL2
40620 GOSUB 30800 'pushlab
40630 GOSUB 30800 'pushlab
40999 RETURN
41000 '----------
41010 ' proc elseif
41020 '
41030 GOSUB 30900 'poplab
41040 TVAL1=LABELVAL
41060 GOSUB 30900 'poplab
41070 POUT$="GOTO "+LABEL$
41080 GOSUB 30100 'put
41090 GOSUB 30200 'putline
41092 TVAL2=LABELVAL
41094 LABELVAL=TVAL1
41096 GOSUB 50100 'place glab
41098 LABELVAL=TVAL2
41120 GOSUB 30800 'pushlab
41130 GOSUB 30600 'genlab
41135 GOSUB 30800 'pushlab
41140 POUT$="IF NOT("
41150 GOSUB 30100 'put
41160 GOSUB 50500 'scan nb
41190 GOSUB 59000 'copy to eol
41200 POUT$=") THEN "+LABEL$
41210 GOSUB 30100 'put
41220 GOSUB 30200 'putline
41499 RETURN
41500 '----------
41510 ' proc endif
41520 '
41530 GOSUB 30900 'poplab
41531 GOSUB 50100 'place glab
41535 GOSUB 30900 'poplab
41540 GOSUB 50100 'place glab
41999 RETURN
42000 '----------
42010 ' proc repeat
42020 '
42030 GOSUB 30600 'genlab
42040 GOSUB 30800 'pushlab
42050 GOSUB 50100 'place glab
42070 GOSUB 30600 'genlab
42080 GOSUB 30800 'pushlab
42090 GOSUB 50500 'scan nb
42100 IF TTYPE <> SNAME OR TOKEN$ <> "WHILE" THEN 42130
42110 GOSUB 42500 'proc while
42120 GOTO 42170
42130 IF TTYPE <> SNAME OR TOKEN$ <> "UNTIL" THEN 42170
42140 GOSUB 43000 'proc until
42170 'endif
42499 RETURN
42500 '----------
42510 ' proc while
42520 '
42530 GOSUB 30900 'poplab
42540 GOSUB 30800 'pushlab
42550 POUT$="IF NOT("
42560 GOSUB 30100 'put
42580 GOSUB 50500 'scan nb
42590 GOSUB 59000 'copy to eol
42600 POUT$=") THEN "+LABEL$
42605 GOSUB 30100 'put
42610 GOSUB 30200 'putline
42999 RETURN
43000 '----------
43010 ' proc until
43020 '
43030 GOSUB 30900 'poplab
43040 GOSUB 30800 'pushlab
43050 POUT$="IF "
43060 GOSUB 30100 'put
43080 GOSUB 50500 'scan nb
43090 GOSUB 59000 'copy to eol
43100 POUT$=" THEN "+LABEL$
43110 GOSUB 30100 'put
43120 GOSUB 30200 'putline
43499 RETURN
43500 '----------
43510 ' proc endrep
43520 '
43530 GOSUB 30900 'poplab
43550 TVAL1=LABELVAL
43560 GOSUB 30900 'poplab
43570 POUT$="GOTO "+LABEL$
43580 GOSUB 30100 'put
43590 GOSUB 30200 'putline
43592 LABELVAL=TVAL1
43594 GOSUB 50100 'place glab
43999 RETURN
44000 '----------
44010 ' proc include
44020 '
44499 RETURN
44500 '----------
44510 ' proc do
44520 '
44550 GOSUB 50500 'scan nb
44560 IF TTYPE=SNAME THEN 44600
44570 ERMSG$="Procedure name missing"
44580 GOSUB 60000 'error
44590 RETURN
44600 'endif
44610 POUT$="GOSUB "
44620 GOSUB 30100 'put
44630 GOSUB 50200 'ulab ref
44700 GOSUB 30200 'putline
44710 GOSUB 50600 'vfy eol
44999 RETURN
45000 '----------
45010 ' proc procedure
45020 '
45030 GOSUB 50500 'scan nb
45040 IF TTYPE=SNAME THEN 45080
45050 ERMSG$="Missing procedure name"
45060 GOSUB 60000 'error
45070 RETURN
45080 POUT$="'----"+TOKEN$
45090 GOSUB 30100 'put
45100 GOSUB 46000 'def ulab
45160 GOSUB 30200 'putline
45170 GOSUB 50600 'vfy eol
45499 RETURN
45500 '----------
45510 ' proc endproc
45520 '
45530 POUT$="RETURN"
45540 GOSUB 30100 'put
45550 GOSUB 30200 'putline
45560 GOSUB 50600 'vfy eol
45599 RETURN
46000 '----------
46010 ' def ulab
46020 '
46030 GOSUB 50300 'lookup ulab
46040 IF LABELINDEX<0 THEN 46130
46050 IF LABELLOC<0 THEN 46090
46060 ERMSG$="multiple definition: "+TOKEN$
46070 GOSUB 60000 'error
46080 GOTO 46110
46090 'else
46095 GLABVALS(65529!+LABELLOC)=OUTNUM
46100 ULABVALS(LABELINDEX)=OUTNUM
46110 'endif
46120 GOTO 46180
46130 'else
46140 ULABVALS(NEXTULAB)=OUTNUM
46150 ULABTEXT$(NEXTULAB)=TOKEN$
46160 NEXTULAB=NEXTULAB+1
46170 IF NEXTULAB>1000 THEN PRINT "Too many labels" : STOP
46180 'endif
46190 GOSUB 50500 'scan nb 'consume : if pres. else fetch eol
46499 RETURN
50000 '----------
50010 ' init symtabs
50020 '
50030 FOR I=0 TO 1000
50040 GLABVALS(I)=-1
50050 ULABVALS(I)=-1
50060 NEXT
50070 NEXTULAB=0
50099 RETURN
50100 '----------
50110 ' place glab
50120 '
50130 GLABVALS(65529!-LABELVAL)=OUTNUM
50199 RETURN
50200 '----------
50205 ' ulab ref
50210 '
50215 GOSUB 50300 'lookup ulab
50220 IF LABELINDEX>=0 THEN 50245
50225 LABELINDEX=NEXTULAB: NEXTULAB=NEXTULAB+1
50230 ULABTEXT$(LABELINDEX)=TOKEN$
50235 GOSUB 30600 'genlab
50240 ULABVALS(LABELINDEX)=-LABELVAL
50245 'endif
50250 POUT$=STR$(ABS(ULABVALS(LABELINDEX)))
50255 GOSUB 30100 'put
50299 RETURN
50300 '----------
50310 ' lookup ulab -- label in 'token$', sets 'labelloc', 'labelindex'
50320 '
50340 IF NEXTULAB=0 THEN LABELINDEX=-1: RETURN
50350 FOR LABELINDEX=0 TO NEXTULAB-1
50360 IF ULABTEXT$(LABELINDEX)<>TOKEN$ THEN 50390
50370 LABELLOC=ULABVALS(LABELINDEX)
50380 RETURN
50390 NEXT
50400 LABELINDEX=-1
50499 RETURN
50500 '----------
50510 ' scan nb
50520 '
50530 GOSUB 20000 'scan
50540 IF TOKEN$=" " THEN 50530
50599 RETURN
50600 '----------
50610 ' vfy eol
50620 '
50630 GOSUB 50500 'scan nb
50640 IF TTYPE=EOL OR TTYPE=CDELIM THEN RETURN
50650 ERMSG$="Extraneous words after statement"
50660 GOSUB 60000 'error
50699 RETURN
51000 '----------
51010 ' init screen
51020 '
51030 CLS
51040 LOCATE 1,1: PRINT USING "\ \ XB V1.00 (13-Mar-83)";TIME$;
51099 RETURN
53000 '----------
53010 ' init files
53020 '
53030 INCHAN=1
53040 OUTCHAN=2
53050 INPUT "Input file: ",INNAME$
53060 INPUT "Output file: ",OUTNAME$
53070 OPEN INNAME$ FOR INPUT AS INCHAN
53080 OPEN OUTNAME$ FOR OUTPUT AS OUTCHAN
53090 RETURN
55000 '----------
55010 ' pass 2
55020 '
55030 GOSUB 30000 'init put
55040 OUTNUM=65529!
55045 OUTLINE$="65529 "
55050 OUTINC=-1
55060 PATCHNR=0
55070 WHILE OUTNUM>NEXTGLAB
55080 POUT$=" GOTO "+STR$(GLABVALS(PATCHNR))
55090 GOSUB 30100 'put
55100 GOSUB 30200 'putline
55105 PATCHNR=PATCHNR+1
55110 WEND
55199 RETURN
55200 '----------
55210 ' finish ulabs
55220 '
55230 IF NEXTULAB=0 THEN RETURN
55240 FOR I=0 TO NEXTULAB-1
55250 IF ULABVALS(I)>=0 THEN 55300
55260 ERMSG$="Undefined label: "+ULABTEXT$(I)
55270 GOSUB 60000 'error
55300 'endif
55310 NEXT
55320 RETURN
55500 '----------
55510 'finish errs
55520 '
55530 CLS
55540 IF ERCNT=0 THEN PRINT "No errors detected" ELSE PRINT USING "#### error(s) detected"; ERCNT
55599 RETURN
59000 '----------
59010 ' copy to eol
59020 '
59030 WHILE TTYPE<>EOL
59040 IF TTYPE<>ULAB THEN 59100
59050 GOSUB 50200 'ulab ref
59060 GOTO 59200
59100 'else
59110 POUT$=TOKEN$
59120 GOSUB 30100 'put
59200 'endif
59205 GOSUB 20000 'scan
59210 WEND
59299 RETURN
60000 '----------
60010 ' error -- displays 'ermsg$'
60020 '
60030 ERCNT=ERCNT+1
60040 PRINT "XB Error: ";
60050 PRINT ERMSG$
60070 RETURN